<template>
  <q-table
    :rows="tableData"
    :columns="computedColumns"
    :row-key="rowKey"
    :selection="selection"
    :selected="selectedRows"
    @update:selected="handleSelectionUpdate"
    :pagination="pagination"
    :loading="loading"
    class="fy-table"
  >
    <!-- 顶部工具栏 -->
    <template #top>
      <div class="q-table__top row items-center justify-between q-px-md q-py-sm">
        <slot name="top-left">
          <div class="text-h6">{{ title }}</div>
        </slot>
        <slot name="top-right" />
      </div>
    </template>

    <!-- 自定义行 -->
    <template #body="props">
      <q-tr :props="props">
        <!-- 选择列 -->
        <q-td v-if="selection === 'multiple'" auto-width>
          <q-checkbox v-model="props.selected" />
        </q-td>
        <q-td v-else-if="selection === 'single'" auto-width>
          <q-radio v-model="selectedRow" :val="props.row" />
        </q-td>

        <!-- 数据列 -->
        <q-td v-for="col in props.cols" :key="col.name" :props="props">
          <slot :name="`body-cell-${col.name}`" :row="props.row" :col="col">
            {{ getColumnValue(props.row, col) }}
          </slot>
        </q-td>
      </q-tr>
    </template>

    <!-- 无数据时的提示 -->
    <template #no-data>
      <div class="full-width row flex-center q-pa-md text-grey">暂无数据</div>
    </template>

    <!-- 添加 loading 插槽 -->
    <template #loading>
      <div class="full-width row flex-center q-pa-md text-grey">
        <q-spinner color="primary" size="2em" />
        <div class="q-ml-sm">加载中...</div>
      </div>
    </template>
  </q-table>
</template>

<script setup>
import { ref, computed, watch } from 'vue'

const props = defineProps({
  tableData: {
    type: Array,
    required: true,
  },
  columns: {
    type: Array,
    required: true,
  },
  title: {
    type: String,
    default: '',
  },
  rowKey: {
    type: String,
    default: 'id',
  },
  selection: {
    type: String,
    default: '',
  },
  selected: {
    type: [Array, Object],
    default: () => [],
  },
  loading: {
    type: Boolean,
    default: false,
  },
})

const emit = defineEmits(['update:selected', 'selection'])

// 计算列配置
const computedColumns = computed(() => {
  const cols = [...props.columns]
  if (props.selection) {
    cols.unshift({
      name: 'selection',
      label: '',
      field: 'selection',
      required: true,
      align: 'left',
      sortable: false,
    })
  }
  return cols
})

// 选择相关
const selectedRows = ref(Array.isArray(props.selected) ? [...props.selected] : [])
const selectedRow = ref(props.selected)

// 处理选择更新
const handleSelectionUpdate = (val) => {
  if (props.selection === 'multiple') {
    selectedRows.value = val
    emit('update:selected', val)
    emit('selection', val)
  }
}

// 监听外部选中值变化
watch(
  () => props.selected,
  (newVal) => {
    if (props.selection === 'single') {
      selectedRow.value = newVal
    } else if (props.selection === 'multiple' && !isEqual(newVal, selectedRows.value)) {
      selectedRows.value = Array.isArray(newVal) ? [...newVal] : []
    }
  },
  { deep: true },
)

// 监听单选变化
watch(selectedRow, (newVal) => {
  if (props.selection === 'single') {
    emit('update:selected', newVal)
    emit('selection', newVal)
  }
})

// 分页配置
const pagination = ref({
  rowsPerPage: 10,
})

// 添加 lodash 的 isEqual 函数或自定义比较函数
function isEqual(arr1, arr2) {
  if (!Array.isArray(arr1) || !Array.isArray(arr2)) return false
  if (arr1.length !== arr2.length) return false
  return arr1.every((item) => arr2.includes(item))
}

// 添加 getColumnValue 方法
const getColumnValue = (row, col) => {
  const fieldValue = col.field || col.name
  const value = typeof fieldValue === 'function' ? fieldValue(row) : row[fieldValue]

  // 检查是否有 format 字段并应用格式化
  if (col.format) {
    return col.format(value)
  }

  return value
}
</script>

<style lang="scss" scoped>
.fy-table {
  :deep(.q-table__top) {
    padding: 8px 16px;
  }

  :deep(.q-table thead tr) {
    th {
      font-weight: 500;
      font-size: 14px;
    }

    th:first-child {
      padding-left: 16px;
    }

    th:last-child {
      padding-right: 16px;
    }
  }

  :deep(.q-table tbody tr) {
    td:first-child {
      padding-left: 16px;
    }

    td:last-child {
      padding-right: 16px;
    }
  }
}

.fy-table {
  border-radius: 8px;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.1);
}
</style>
